%{
#include <math.h>
#include "toktypes.h"

#define MAX_BRACKET_DEPTH 10000

struct {
    char *keyword;
    int kw_type;
} keyword_list[] = {
    "and",   TK_AND, 
    "case",  TK_CASE,
    "else",  TK_ELSE,
    "if",    TK_IF,
    "in",    TK_IN,  
    "let",   TK_LET, 
    "not",   TK_NOT, 
    "of",    TK_OF,  
    "or",    TK_OR,  
    "then",  TK_THEN,
    "xor",   TK_XOR,
    "case",  TK_CASE,
    "or",    TK_OR,
    "and",   TK_AND,
    "in",    TK_IN,
    "",      -1,
};

int bracket_stack[MAX_BRACKET_DEPTH];
int bracket_stack_ptr = 0;
%}

DIGIT [0-9]
ID [a-z][a-z0-9\?\!_]*
SYMBOL [A-Z][a-z0-9_]*
%%
{ID} {
    int i;
    for (i = 0; strlen(keyword_list[i].keyword) > 0; ++i) {
        if (!stricmp(keyword_list[i].keyword, yytext)) {
            printf("keyword: %s\n", yytext);
        }
    }
    printf("variable: %s\n", yytext);
}

{DIGIT}+"."{DIGIT}+(|"E"(|"+"|"-"){DIGIT}+) {
    printf("number: %s\n", yytext);
}

"#[" {
    printf("left array bracket\n");
    bracket_stack[bracket_stack_ptr++] = TK_R_ARRAY_BRACK;
}

"[" {
    printf("left list bracket\n");
    bracket_stack[bracket_stack_ptr++] = TK_R_LIST_BRACK;
}

"#h[" {
    printf("left hash bracket\n");
    bracket_stack[bracket_stack_ptr++] = TK_R_HASH_BRACK;
}

"{" {
    printf("left closure bracket\n");
    bracket_stack[bracket_stack_ptr++] = TK_R_CLOSURE_BRACK;
}

"]" {
    if (bracket_stack_ptr > 0) {
        switch(bracket_stack[--bracket_stack_ptr]) {
            case TK_R_ROUND_BRACK:
                printf("right round bracket\n");
                break;
            case TK_R_LIST_BRACK:
                printf("right list bracket\n");
                break;
            case TK_R_CLOSURE_BRACK:
                printf("right closure bracket\n");
                break;
            case TK_R_ARRAY_BRACK:
                printf("right array bracket\n");
                break;
            case TK_R_HASH_BRACK:
                printf("right hash bracket\n");
                break;
        }
    } else {
        printf("unmatched bracket (%s)\n", yytext);
    }            
}

"+" {
    printf("addition operator\n");
}

"++" {
    printf("append operator\n");
}

"-" {
    printf("subtraction operator\n");
}

"*" {
    printf("multiplication operator\n");
}

"**" {
    printf("exponentiation operator\n");
}

"," {
    printf("tuple append operator\n");
}

"=" {
    printf("equal operator\n");
}

"\\" {
    printf("row end operator\n");
}

"." {
    printf("index operator\n");
}

":=" {
    printf("assignment operator\n");
}

"\n" {
    printf("newline\n");
}

"_" {
    printf("anonymous variable\n");
}

